#ifndef TCP_CONNECTION_HPP
#define TCP_CONNECTION_HPP

#include "Acceptor.hpp"
#include <memory>
#include <functional>

using std::function;
using std::shared_ptr;

class TcpConnection;  // 前向声明 TcpConnection 类
using TcpConnectionPtr = shared_ptr<TcpConnection>;
using TcpConnectionCallback = function<void(const TcpConnectionPtr &)>;

// SocketIO 类 -------------------------------------------------------------
// 封装一个通信用的fd，以及收发数据的细节操作，即send和recv等系列操作
class SocketIO { 
public:
    explicit SocketIO(int fd);
    ~SocketIO();
    size_t readn(char *buf, size_t len);          // 读取len个字节（可超过C函数recv函数单次读取数据量的上限）
    size_t writen(const char *buf, size_t len);   // 写出len个字节（可超过C函数send函数单次读取数据量的上限）
    size_t readline(char *buf, size_t len);       // 读取一行数据（以换行符为标志）

private:
    int _fd;
};


// TcpConnection 类 -------------------------------------------------------------
// 封装一条已建立的有效连接，基于该连接进行数据的发送和接收
class EventLoop;   // 前向声明Eventloop类；在TcpConnection.cpp中引入Eventloop的头文件

class TcpConnection 
: public std::enable_shared_from_this<TcpConnection>
{
public:
    explicit TcpConnection(int fd, EventLoop * loop);
    ~TcpConnection();
    string toString() const;   // 完整连接信息
    string peerToString() const;  // 对端地址信息
    void send(const string &msg);   // 发送数据
    string recv();    // 接收数据
    bool isClosed() const;  // 检测对端是否已断开连接
    void setNewConnectionCallback(TcpConnectionCallback & cb);
    void setMessageCallback(TcpConnectionCallback & cb);
    void setCloseCallback(TcpConnectionCallback & cb);
    void handleNewConnectionCallback();  // 使用回调函数
    void handleMessageCallback();
    void handleCloseCallback();

    // 帮助线程池子线程与主线程交互
    void sendInLoop(const string &msg);  // 发送"send()"任务到主线程（在子线程中调用）
                                         // 在函数内部调用_loop->runInLoop(Functor && cb)

private:
    InetAddress getLocalAddr();  // 获取本端地址
    InetAddress getPeerAddr();   // 获取对端地址
    
private:
    SocketIO _sockio;        // 专门用于通信
    Socket _sock;            // 用于提供fd，提供连接的地址信息
    InetAddress _localAddr;  // 本端地址
    InetAddress _peerAddr;   // 对端地址

    // 由用户指定对三个事件的处理方式（回调）
    TcpConnectionCallback _onNewConnection; // 处理新建连接（信息打印）
    TcpConnectionCallback _onMessage;       // 处理客户端到达消息（io操作）
    TcpConnectionCallback _onClose;         // 处理客户端连接关闭（信息打印）

    // 帮助线程池子线程与主线程交互
    EventLoop * _loop;   // 在TcpConnection对象中可以感知到s事件循环loop的存在
};


#endif // TCP_CONNECTION_HPP